package com.itheima.service.impl;

import com.itheima.mapper.DeptMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Dept;
import com.itheima.pojo.DeptLog;
import com.itheima.service.DeptLogService;
import com.itheima.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

@Service //交给spring管理
@Slf4j
public class DeptServiceImpl implements DeptService {
    // 会依赖 mapper层 完成数据库数据的增删改查
    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private EmpMapper empMapper;//因为我们要删除员工信息 用员工表的操作接口

    @Autowired
    private DeptLogService deptLogService;

    @Override
    public List<Dept> list() {
        // 数据 数据库才有  臣妾没有 找秘书。。
        List<Dept> deptList = deptMapper.list();
        return deptList;//不要忘记 返回
    }
   /*
     如果不加事务控制
       部门删除了 有可能员工还没删除，这样的话 这件事就有问题了
       部门如果删除了，但是在删除员工的时候出现问题，部门也要保留。。
       也就是 删除部门操作和删除该部门下员工操作 是一个整体
       要么同时成功 要么同时失败
     需要 对 这两个sql进行 事务操作  也就要 开启事务 回滚事务 提交事务
           try{
                // 开启事务
                // 执行 多个 sql --整体

                // 提交事务
            }catch (){
                // 事务回滚
            }finally {
                //最终执行的
            }
       上述的事务控制，我们已经不写了。。
       spring框架 提供了一个注解
         @Transactional   事务标注注解
          用在  类上  接口上 方法上
            类上  类中所有方法都加事务控制
            接口上  实现类中所有实现的方法都加事务控制
            方法上  当前方法 加入事务控制
         哪里需要加到哪里，保证该方法中的语句 要么 同时成功 要么同时失败
    */
    @Override
    @Transactional(rollbackFor = Exception.class)//Exception及其子类 异常 都会完成回滚
    // 默认只针对运行期异常 出现运行期异常才会进行事务控制(回滚)
    // 如果遇到 编译期异常 不会回滚
    public void delete(Integer id)throws Exception {
        // 遣散部门
       try{
           // 部门删除
           deptMapper.deleteById(id);
           log.info("删除了部门的信息  在部门表  一条sql");

           // 万一出现了个异常！！
//        System.out.println(1/0);//这是数学异常  默认程序中 遇到异常
           // 1/0 是运行期异常  出现运行期异常 回滚了
           // 重写的方法 抛出的异常 只能是 重写前方法 的子集
           if(true){
               throw new Exception("我是编译期异常 我怕谁");
               // 抛 出一个异常
           }
           // 跟部门相关的员工也要删除
           empMapper.deleteByDeptId(id);//根据部门id删除 该部门下所有的员工
           log.info("删除部门下的员工信息  在员工表  一条sql");//这种日志 在控制台 日志文件中
       }finally {//最终都会执行的
           // 不管 是不是有异常 我们都执行 记录日志功能
           DeptLog deptLog = new DeptLog();
           deptLog.setCreateTime(LocalDateTime.now());
           deptLog.setDescription("执行了解散部门操作，此时解散的是:"+id+"号部门");

           deptLogService.insert(deptLog);
       }



    }

    @Override
    public void add(Dept dept) {
        // dept 只有 一个字段
        // id  createTime  updateTime
        // id 字段 自增 不用补充
        // 补全 dept字段
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        // 让 mapper完成添加
        deptMapper.insert(dept);//把 dept添加对象 传递过去
    }
}
